import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.security.KeyPair;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class Tracker extends Thread{
    Address address;
    Map<Integer, ArrayList<Address>> sourceNodes = new HashMap<>();
    ServerSocket serverSocket;
    ArrayList<TrackerListener> connections = new ArrayList<>();
    public Tracker(Address address) {
        try {
            this.address = address;
            serverSocket = new ServerSocket(address.port);
            System.out.println("等待连接中。。。");
        }
        catch (Exception e) {
            System.out.println(e.toString());
        }
    }

    public static void main(String[] args)  {
        Tracker tracker = new Tracker(new Address("127.0.0.1", 1234));
        tracker.start();
        while (tracker.isAlive()) {
            try {
                sleep(10000);
                System.out.println("tracker服务器正在运行......");
            }
            catch (Exception e) {
            }

        }
    }

    @Override
    public void run() {
        while (!serverSocket.isClosed()) {
            try {
                Socket client = serverSocket.accept();
                //客户端socket地址
                BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                PrintWriter out = new PrintWriter(client.getOutputStream(), true);
                TrackerListener trackerListener = new TrackerListener(client, in, out);
                connections.add(trackerListener);
                trackerListener.start();
            }
            catch (Exception e) {
                System.out.println(e.toString());
            }
        }
    }

    /*添加下载节点*/
    public void addNode(Integer index, Address address) {
        sourceNodes.get(index).add(address);
    }

    /*注销下载节点*/
    public void deleteNode(Integer index, Address address) {
        sourceNodes.get(index).remove(address);
    }

    class TrackerListener extends Thread{
        Socket socket;
        BufferedReader in;
        PrintWriter out;
        Address address;
        public TrackerListener(Socket socket, BufferedReader in, PrintWriter out) {
            this.socket = socket;
            this.in = in;
            this.out = out;
            address = new Address(socket);
        }
        @Override
        public void run() {
            Message message = null;
            while (!socket.isClosed()) {
                try {
                    message = JSONObject.parseObject(in.readLine(), Message.class);
                    if (message.operation.equals("exit"))
                        close();
                    /*请求得到资源下载节点信息*/
                    if (message.operation.equals("getDownloadAddress")) {
//                        sourceNodes.get(message.index);
                    }
                    /*增加资源信息*/
                    if (message.operation.equals("addSource")) {
                        System.out.println("添加资源");
                        ArrayList<Address>addresses = new ArrayList<>();
                        addresses.add(new Address(socket.getLocalAddress().getHostAddress(), socket.getLocalPort()));
                        Integer torrentIndex = generateTorrentIndex();
//                        System.out.println(torrentIndex);
                        sourceNodes.put(torrentIndex,addresses);
                        Message message1 = new Message("generatedTorrentIndex",torrentIndex);
                        System.out.println(message1.index);
                        out.println(JSON.toJSONString(message1));
                    }
                } catch (Exception e) {
                    System.out.println(e);
                    System.out.println(address.ip + ":" + address.port + " 连接中断");
                    close();
                }
            }
        }
        public void close() {
            try {
                this.in.close();
                this.out.close();
                this.socket.close();
            }
            catch (Exception e) {
                System.out.println(e.toString());
            }
        }

        public int generateTorrentIndex(){
            return sourceNodes.size()+1;
        }

    }

}
